﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web;
using ZhongKeSite.Common.Helper;

namespace ZhongKeSite.Common
{
    public sealed class IdentityCreator
    {
        /*
         * var guid = Guid.NewGuid();
         * guid.ToString("D")   10244798-9a34-4245-b1ef-9143f9b1e68a
         * guid.ToString("N")   102447989a344245b1ef9143f9b1e68a
         * guid.ToString("B")   {10244798-9a34-4245-b1ef-9143f9b1e68a}
         * guid.ToString("P")   (10244798-9a34-4245-b1ef-9143f9b1e68a)
         * 不区另大小写
         */
        public static string NextIdentity
        {
            get
            {
                string nextIdentity = DateTime.Now.ToString("yyMMddHHmmssfffff") + Guid.NewGuid().ToString("N").Substring(new Random().Next(0, 17), 8);
                return nextIdentity.ToUpper();
            }
        }

        public static int timestamp
        {
            get
            {
                return ((Int32)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
            }
        }

        private static object BillLock = new object();
        /// <summary>
        ///  生成一定规则的订单号--长度大于20小于41位
        /// </summary>
        /// <param name="len">订单号长度</param>
        /// <returns></returns>
        public static string GetBillNo(int len)
        {
            lock (BillLock)
            {
                string result = DateTime.Now.ToString("yyMMddHHmmssfffff");
                int length = len - result.Length;
                result = result + Guid.NewGuid().ToString("N").Substring(new Random().Next(0, 17), length);
                return result;
            }
        }
        /// <summary>
        ///  生成一定规则的订单号--数字
        /// </summary>
        /// <param name="len">订单号长度</param>
        /// <returns></returns>
        public static string GetRandomNo(int len)
        {
            lock (BillLock)
            {
                string result = DateTime.Now.ToString("HHmmssffff");
                int n = len - result.Length;
                Random r = new Random(unchecked((int)DateTime.Now.Ticks));
                result = result + GetRandom(r, n);
                return result;
            }
        }
        private static string GetRandom(Random r, int len)
        {
            string num = "";
            System.Threading.Thread.Sleep(1);
            for (int i = 0; i < len; i++)
            {
                num += r.Next(0, 9);
            }
            return num;
        }
        public static string GetMerchantNo()
        {
            return string.Format("888{0}", GetSecret(7, true));
        }
        public static string GetAgentID()
        {
            return string.Format("666{0}", GetSecret(7, true));
        }
        public static string GetOrderNo()
        {
            string nextIdentity = DateTime.Now.ToString("yyMMddHHmmssfffff") + Guid.NewGuid().ToString("N").Substring(new Random().Next(0, 17), 8);
            return nextIdentity.ToUpper();
        }
        public static string GetSecret(int intLength, bool booNumber = false, bool booSign = false, bool booSmallword = false, bool booBigword = false)
        {
            //定义
            Random ranA = new Random();
            int intResultRound = 0;
            int intA = 0;
            string strB = "";
            while (intResultRound < intLength)
            {
                //生成随机数A，表示生成类型
                //1=数字，2=符号，3=小写字母，4=大写字母
                intA = ranA.Next(1, 5);
                //如果随机数A=1，则运行生成数字
                //生成随机数A，范围在0-10
                //把随机数A，转成字符
                //生成完，位数+1，字符串累加，结束本次循环
                if (intA == 1 && booNumber)
                {
                    intA = ranA.Next(0, 10);
                    strB = intA.ToString() + strB;
                    intResultRound = intResultRound + 1;
                    continue;
                }
                //如果随机数A=2，则运行生成符号
                //生成随机数A，表示生成值域
                //1：33-47值域，2：58-64值域，3：91-96值域，4：123-126值域
                if (intA == 2 && booSign == true)
                {
                    intA = ranA.Next(1, 5);
                    //如果A=1
                    //生成随机数A，33-47的Ascii码
                    //把随机数A，转成字符
                    //生成完，位数+1，字符串累加，结束本次循环
                    if (intA == 1)
                    {
                        intA = ranA.Next(35, 39);//ranA.Next(33, 48);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                    //如果A=2
                    //生成随机数A，58-64的Ascii码
                    //把随机数A，转成字符
                    //生成完，位数+1，字符串累加，结束本次循环
                    if (intA == 2)
                    {
                        intA = ranA.Next(97, 123);//ranA.Next(58, 65);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                    //如果A=3
                    //生成随机数A，91-96的Ascii码
                    //把随机数A，转成字符
                    //生成完，位数+1，字符串累加，结束本次循环
                    if (intA == 3)
                    {
                        intA = ranA.Next(42, 44); //ranA.Next(91, 97);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }

                    //如果A=4
                    //生成随机数A，123-126的Ascii码
                    //把随机数A，转成字符
                    //生成完，位数+1，字符串累加，结束本次循环
                    if (intA == 4)
                    {
                        intA = ranA.Next(65, 89);//ranA.Next(123, 127);
                        strB = ((char)intA).ToString() + strB;
                        intResultRound = intResultRound + 1;
                        continue;
                    }
                }

                //如果随机数A=3，则运行生成小写字母
                //生成随机数A，范围在97-122
                //把随机数A，转成字符
                //生成完，位数+1，字符串累加，结束本次循环
                if (intA == 3 && booSmallword == true)
                {
                    intA = ranA.Next(97, 123);
                    strB = ((char)intA).ToString() + strB;
                    intResultRound = intResultRound + 1;
                    continue;
                }

                //如果随机数A=4，则运行生成大写字母
                //生成随机数A，范围在65-90
                //把随机数A，转成字符
                //生成完，位数+1，字符串累加，结束本次循环
                if (intA == 4 && booBigword == true)
                {
                    intA = ranA.Next(65, 89);
                    strB = ((char)intA).ToString() + strB;
                    intResultRound = intResultRound + 1;
                    continue;
                }
            }
            return strB;
        }
    }

    public static class Utils
    {
        public static bool IsAjaxRequest(this HttpRequest req)
        {
            bool result = false;
            var xreq = req.Headers.ContainsKey("x-requested-with");
            if (xreq)
            {
                result = req.Headers["x-requested-with"] == "XMLHttpRequest";
            }
            return result;
        }
        public static object GetPropertyValue(this object m, string name)
        {
            return m.GetType().GetProperty(name).GetValue(m) ?? string.Empty;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string ToSafeString(this string text)
        {
            if (string.IsNullOrEmpty(text))
                return text;
            return text.Replace("'", "''");
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string ToJoinStr(this List<string> text, string format = "'{0}',")
        {
            string s = string.Empty;
            foreach (object o in text)
            {
                if (o != null)
                {
                    s += string.Format(format, o.ToString());
                }
            }
            return s.TrimEnd(',');
        }

        /// <summary>
        /// 添加url地址参数
        /// </summary>
        /// <param name="text"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public static string ToConcatQueryString(this string text, string query)
        {
            bool hasConnect = text.IndexOf("?") > -1;
            if (hasConnect)
            {
                bool hasReplace = query.IndexOf("=") > -1 && text.IndexOf(query.Substring(0, query.IndexOf("=") + 1)) > -1;
                if (hasReplace)
                {
                    string qn = query.Substring(0, query.IndexOf("=") + 1);
                    string qf = text.Substring(0, text.IndexOf(qn));
                    bool hasOtherQuery = text.Substring(qf.Length).IndexOf("&") > -1;
                    string ql = hasOtherQuery ? text.Substring(qf.Length + text.Substring(qf.Length).IndexOf("&")) : "";
                    return string.Format(qf + "{0}" + ql, query);
                }
                else
                {
                    return text + "&" + query;
                }
            }
            else
            {
                return text + "?" + query;
            }
        }
        /// <summary>
        /// 在前面补充字符
        /// </summary>
        /// <param name="text"></param>
        /// <param name="l"></param>
        /// <param name="padStr"></param>
        /// <returns></returns>
        public static string ToPadBefore(this string text, int l, string padStr = " ")
        {
            string s = string.Empty;
            while (l > 0)
            {
                l--;
                s += padStr;
            }
            return s + text;
        }
        /// <summary>
        /// 将集合类转换成DataTable
        /// </summary>
        /// <param name="list">集合</param>
        /// <returns></returns>
        public static DataTable ToDataTable(this IList list)
        {
            DataTable result = new DataTable();
            if (list.Count > 0)
            {
                PropertyInfo[] propertys = list[0].GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition().GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        result.Columns.Add(pi.Name, pi.PropertyType.GetGenericArguments()[0]);
                    }
                    else
                    {
                        result.Columns.Add(pi.Name, pi.PropertyType);
                    }
                }

                for (int i = 0; i < list.Count; i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in propertys)
                    {
                        object obj = pi.GetValue(list[i], null) == null ? DBNull.Value : pi.GetValue(list[i], null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    result.LoadDataRow(array, true);
                }
            }
            return result;
        }
        /// <summary>
        /// ilist to list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="gbList"></param>
        /// <returns></returns>
        public static List<T> ToCList<T>(this IList gbList) where T : class
        {
            if (gbList != null && gbList.Count >= 1)
            {
                List<T> list = new List<T>();
                PropertyInfo[] propertys = typeof(T).GetProperties();
                PropertyInfo[] propertys_1 = gbList[0].GetType().GetProperties();
                T t;
                for (int i = 0; i < gbList.Count; i++)
                {
                    t = Activator.CreateInstance<T>();
                    foreach (var item in propertys)
                    {

                        if (propertys_1.Where(a => a.Name == item.Name).Count() == 1)
                        {
                            var o = propertys_1.Where(a => a.Name == item.Name).FirstOrDefault();
                            var v = o.GetValue(gbList[i], null);
                            item.SetValue(t, v, null);
                        }
                    }
                    list.Add(t);

                }
                return list;
            }
            return null;
        }
        /// <summary>
        /// 比较字符串忽略大小写
        /// </summary>
        /// <param name="originString"></param>
        /// <param name="compareString"></param>
        /// <returns></returns>
        public static bool EqualsIgnoreCase(this string originString, string compareString)
        {
            if (compareString == null)
            {
                return false;
            }
            if (originString.ToLower().Equals(compareString.ToLower()))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 比较字符串是否相等
        /// </summary>
        /// <param name="originString"></param>
        /// <param name="compareString"></param>
        /// <returns></returns>
        public static bool NotEquals(this string originString, string compareString)
        {
            if (compareString == null)
            {
                return false;
            }
            if (!originString.Equals(compareString))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 客户端IP
        /// </summary>
        /// <returns></returns>
        public static string GetIP(this HttpContext httpContext)
        {
            try
            {
                return httpContext.Connection.RemoteIpAddress.ToString();
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                return "127.0.0.1";
            }
        }
        /// <summary>
        /// 去除html代码
        /// </summary>
        /// <param name="Htmlstring"></param>
        /// <returns></returns>
        public static string ToNoHtml(this string Htmlstring)
        {
            if (string.IsNullOrEmpty(Htmlstring))
            {
                return string.Empty;
            }

            //删除脚本
            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
            //删除HTML
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);

            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(ndash);", "–", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(mdash);", "—", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(rdquo);", "”", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(ldquo);", "“", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);

            Htmlstring.Replace("<", "");
            Htmlstring.Replace(">", "");
            Htmlstring.Replace("\r\n", "");
            Htmlstring = HttpUtility.HtmlEncode(Htmlstring).Trim();
            return Htmlstring;
        }
        public static string GetBillNo()
        {
            string empty = string.Empty;
            empty = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            Random random = new Random((int)DateTime.Now.Ticks);
            //int num = random.Next(0, 99999);

            //byte[] buffer = Guid.NewGuid().ToByteArray();
            //var num = BitConverter.ToInt64(buffer, 0);

            //empty = string.Concat(empty, num.ToString().Substring(0, 6));
            //empty = string.Concat(empty, Orders.GetOrderCountToday().PadRight(10, '0'));
            return empty;
        }
    }
}
